/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package scheduler.view.windows;

import java.io.IOException;
import java.net.URL;
import java.util.HashSet;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import scheduler.core.Processor;
import scheduler.core.utils.Point;
import scheduler.core.utils.ValidationException;
import scheduler.view.dialogs.DialogUtils;

/**
 * FXML Controller class
 *
 * @author Dima
 */
public class ResultsWindowController implements Initializable {

    @FXML
    private LineChart<Number, Number> graphic;
    @FXML
    private ChoiceBox<String> priority;
//=====================  Перша група вихідних даних ========================//
    @FXML
    private TextField Ti;
    @FXML
    private TextField N;
    @FXML
    private TextField Tpi;
    @FXML 
    private TextField Ai;
    @FXML 
    private TextField Tpij;
//=====================  Друга група вихідних даних ========================//
    @FXML
    private TextField P0_2; // P0(i)
    @FXML
    private TextField Ro_2; // ρ
    @FXML
    private TextField lambdai; // λ(i)
    @FXML
    private TextField nui; // ν(i)
    @FXML
    private TextField lambda_2; // λ
    @FXML
    private TextField nu_2; // ν
    @FXML
    private TextField n_2; // n
    @FXML
    private TextField ni; // n(i)
//=====================  третя група вихідних даних ========================//
    @FXML
    private TextField P0_1; // P0(1,2,...,i-1)
    @FXML
    private TextField Ro_1; // ρ
    @FXML
    private TextField lambda_1; // λ
    @FXML
    private TextField nu_1; // ν
    @FXML
    private TextField n_1; // n
    
    @FXML
    private ToggleButton showGraph1;
    @FXML
    private ToggleButton showGraph2;
    @FXML
    private ToggleButton showGraph3;
    
    private Processor processor;
    private int priorityNum;
    
    private String textUnderGraph = "T(i) - cередній час виконання задачі для і-го пріоритету";
    
    

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        NumberAxis xAxis = (NumberAxis) graphic.getXAxis();
        
        showGraph1.selectedProperty().addListener(new ChangeListener<Boolean>() {

            @Override
            public void changed(ObservableValue<? extends Boolean> ov, Boolean oldVal, Boolean newVal) {
                if (newVal) {
                    graphic.getYAxis().setLabel("");
                    textUnderGraph = "T(i) - cередній час виконання задач для і-го пріоритету";
                    drawGraph(processor.getTiPoints());
                    showGraph2.setSelected(false);
                    showGraph3.setSelected(false);
                }
            }
        });
        showGraph2.selectedProperty().addListener(new ChangeListener<Boolean>() {

            @Override
            public void changed(ObservableValue<? extends Boolean> ov, Boolean oldVal, Boolean newVal) {
                if (newVal) {
                    graphic.getYAxis().setLabel("");
                    textUnderGraph = "Tp(i) - cередній час виконання окремої задачі для і-го пріоритету, враховуючи час очікування в черзі";
                    drawGraph(processor.getTpiPoints());
                    showGraph1.setSelected(false);
                    showGraph3.setSelected(false);
                }
            }
        });
        
        showGraph3.selectedProperty().addListener(new ChangeListener<Boolean>() {

            @Override
            public void changed(ObservableValue<? extends Boolean> ov, Boolean oldVal, Boolean newVal) {
                if (newVal) {
                    graphic.getYAxis().setLabel("");
                    textUnderGraph = "Tp(i)(j) - cередній час виконання j-ї задачі і-го пріоритету, враховуючи час очікування в черзі";
                    drawGraph(processor.getTpijPoints());
                    showGraph1.setSelected(false);
                    showGraph2.setSelected(false);
                }
            }
        });
        
    }
    
    private void showPriorityResults(int prior) {
        try {
            processor.calc(prior);
        } catch (ValidationException ex) {
            try {
                DialogUtils.showErrorDialog("Internal error: " + ex.getMessage());
                return;
            } catch (IOException ex1) {
                Logger.getLogger(ResultsWindowController.class.getName()).log(Level.SEVERE, null, ex1);
            }
        }
        Ai.setText(String.valueOf(processor.getAi()));
        Ti.setText(String.valueOf(processor.getTi()));
        Tpi.setText(String.valueOf(processor.getTpi()));
        Tpij.setText(String.valueOf(processor.getTpij()));
        N.setText(String.valueOf(processor.getN()));
        P0_2.setText(String.valueOf(processor.getP0_2()));
        Ro_2.setText(String.valueOf(processor.getRo_2()));
        lambdai.setText(String.valueOf(processor.getLambdai()));
        nui.setText(String.valueOf(processor.getNui()));
        lambda_2.setText(String.valueOf(processor.getLambda_2()));
        nu_2.setText(String.valueOf(processor.getNu_2()));
        n_2.setText(String.valueOf(processor.getN_2()));
        ni.setText(String.valueOf(processor.getNi()));
        P0_1.setText(String.valueOf(processor.getP0_1()));
        Ro_1.setText(String.valueOf(processor.getRo_1()));
        lambda_1.setText(String.valueOf(processor.getLambda_1()));
        nu_1.setText(String.valueOf(processor.getNu_1()));
        n_1.setText(String.valueOf(processor.getN_1()));
    }

    private Set<Integer> getPriors() {
        Set<Integer> res = new HashSet<>();

        for (Point p : processor.getTiPoints()) {
            res.add((int)p.getX());
        }

        return res;
    }

    public void setProcessor(Processor processor) {
        this.processor = processor;
        List<Point> points = processor.getTiPoints();
        priorityNum = points.size();

        for (Integer i : getPriors()) {
            priority.getItems().add(String.valueOf(i));
        }
        
        priority.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {

            @Override
            public void changed(ObservableValue<? extends String> ov, String oldValue, String newValue) {
                showPriorityResults(Integer.valueOf(newValue));
            }
        });
        priority.getSelectionModel().selectFirst();
        showGraph1.setSelected(true);
    }

    private void drawGraph(List<Point> points) {
        NumberAxis xAxis = (NumberAxis) graphic.getXAxis();
        ((NumberAxis) graphic.getXAxis()).setLowerBound(1);
        ((NumberAxis) graphic.getXAxis()).setUpperBound(points.size() + 1);
        
        XYChart.Series<Number, Number> series = new XYChart.Series<>();
        series.setName(textUnderGraph);
        //populating the series with data
        for (Point p : points) {
            series.getData().add(new XYChart.Data<Number, Number>(p.getX(), p.getY()));
        }
        
        
        graphic.getData().clear();
        graphic.setAnimated(false);
        graphic.getData().add(series);

    }
}
